#include "as2_t3.h"

#include <stdio.h>

#define LONG_BITCOUNT			(sizeof(long) * 8)
#define BLOCK_BITMASK_OFFSET	(LONG_BITCOUNT * sizeof(task_t))
#define BLOCKSIZE				(BLOCK_BITMASK_OFFSET + sizeof(long))

extern void *_sbrk(int);
extern int _brk(void *);
void* memStart;		/* initial _sbrk(0) value */
void* memEnd;		/* end of allocated memory; for checking when more memory must be allocated */
int memNoCurrent;		/* number of the latest allocated or freed block of task_t's */

int getTask_allocIndex(void* ptr_block, unsigned long bitMask) {
	int result;
	/* number of bits to shift; also the number of 1's in bitMask */
	char stepSize = LONG_BITCOUNT;
	unsigned long full = 0;
	/* if there are task_t's allocated in this block; half the bitmask */
	printf("Hi from getTask_allocIndex!\n");
	printf("pointer to ptr_block_mask: %p\n", (long*)((int)ptr_block + BLOCK_BITMASK_OFFSET));
	printf("compare: %032b\n", *((long*)((int)ptr_block + BLOCK_BITMASK_OFFSET)));
	while (*((long*)((int)ptr_block + BLOCK_BITMASK_OFFSET)) & bitMask) {
		printf("bitMask: %032b,full: %032b\n", bitMask, full);
		/* check if it's time to decrease the stepsize */
		if ((*((long*)((int)ptr_block + BLOCK_BITMASK_OFFSET)) & bitMask) == bitMask) {
			full = full | bitMask;
			/*printf(" full: %032b\n", full);*/
		}
		do {
			if ((bitMask & 3) == 3) {
				stepSize /= 2;
				/* align stepsize 1's to het left of bitMask */
				bitMask <<= LONG_BITCOUNT - stepSize;
				result = 0;
			} else {
				/* shift to right */
				result += stepSize;
				bitMask >>= stepSize;
			}
		} while (bitMask & full);
	}
	return (result + 1) % (LONG_BITCOUNT + 1) - 1;
}

void* task_alloc() {
	int result = -1;
	long* ptr_blockMask;
	
	/* initialize if not already done */
	if (memStart == NULL) {
		memStart = _sbrk(0);
		memEnd = (void*)((int)_sbrk(BLOCKSIZE) + BLOCKSIZE);
		memNoCurrent = 0;
		*(long*)((int)memStart + BLOCK_BITMASK_OFFSET) = 0;
	}
	
	ptr_blockMask = ((long*)((int)(memStart) + memNoCurrent * BLOCKSIZE + BLOCK_BITMASK_OFFSET));
	/*
	printf("block: %032b, and: %b\n", *ptr_blockMask, !~*ptr_blockMask);
	*ptr_blockMask = ~0;
	printf("block: %032b, and: %b\n", *ptr_blockMask, !~*ptr_blockMask);
	*ptr_blockMask = 5;
	printf("block: %032b, and: %b\n", *ptr_blockMask, !~*ptr_blockMask);
	*ptr_blockMask = 0xFFF7FFFF;
	printf("block: %032b, and: %b\n", *ptr_blockMask, !~*ptr_blockMask);
	*/
	
	/* zoek een geheugenblok waarin nog plaatsjes vrij zijn */
	while (!~*ptr_blockMask) {
		memNoCurrent++;
		ptr_blockMask = ((long*)((int)(memStart) + memNoCurrent * BLOCKSIZE + BLOCK_BITMASK_OFFSET));
	}
	/* get next free index in current memory block */
	result = getTask_allocIndex((void*)((int)ptr_blockMask - BLOCK_BITMASK_OFFSET), ~0);
	return (void*)((int)(memStart) + memNoCurrent * BLOCKSIZE + result * sizeof(task_t));
}

void task_free(void *ptr) {
	
}

